package org.warm.meaning.x.base.util.assembler;

import cn.hutool.core.bean.copier.BeanCopier;
import org.warm.meaning.x.base.util.bean.ClassUtil;

import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * command组装类父类，定义公共方法
 *
 * @author SunnyWen at 2021-03-15
 */
public class SuperAssembler {

    private static final String PATTERN_DATE_TIME_MILLIS = "yyyy-MM-dd HH:mm:ss.SSS";

    private static final String PATTERN_DATE_TIME = "yyyy-MM-dd HH:mm:ss";

    private static final String PATTERN_DATE = "yyyy-MM-dd";

    private static final Class<?> CLASS_PAGE_HELPER;
//    private static final Class<?> CLASS_I_PAGE;
//    private static final Class<?> CLASS_I_PAGE_SUB;

    static {
        try {
            ClassUtil util = ClassUtil.build();
            CLASS_PAGE_HELPER = util.forName("com.github.pagehelper.Page");
//            CLASS_I_PAGE = util.forName("com.baomidou.mybatisplus.core.metadata.IPage");
//            CLASS_I_PAGE_SUB = util.forName("com.baomidou.mybatisplus.extension.plugins.pagination.Page");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成一级格式化的时间<br>
     * 日期格式为：yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public Date getCurrentDate() {
        return new Date(System.currentTimeMillis());
    }

    /**
     * 生成一级格式化的时间字符串<br>
     * 日期格式为：yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public String getCurrentDateString() {
        return getDateTimeFormat().format(getCurrentDate());
    }

    /**
     * 生成一级格式化的时间字符串<br>
     * 日期格式为：yyyy-MM-dd
     *
     * @return
     */
    public String getSimpleCurrentDateString() {
        return getDateFormat().format(getCurrentDate());
    }

    /**
     * 生成32位UUID字符串，没有"-"
     *
     * @return
     */
    public String get32BitUuid() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 生成64位UUID字符串，没有"-"
     *
     * @return
     */
    public String get64BitUuid() {
        return UUID.randomUUID().toString().replace("-", "")
                + UUID.randomUUID().toString().replace("-", "");
    }

    public String getMillisRandomId(String prefix, Integer suffixLength) {
        StringBuilder randomBuf = new StringBuilder();
        if (null != suffixLength && suffixLength > 0) {
            final int maxLength = 15;
            int finalSuffixlength = suffixLength;
            int diffSuffixlength = 0;
            if (suffixLength > maxLength) {
                finalSuffixlength = maxLength;
                diffSuffixlength = suffixLength - maxLength;
            }
            Random random = new Random();
            double r = (1 + random.nextDouble()) * Math.pow(10, finalSuffixlength);
            randomBuf.append(String.valueOf((long) r).substring(1));
            while (diffSuffixlength > 0) {
                randomBuf.append("0");
                diffSuffixlength--;
            }

        }
        return (null == prefix ? "" : prefix) + System.currentTimeMillis() + randomBuf;
    }

    /**
     * yyyy-MM-dd HH:mm:ss.SSS
     *
     * @return
     */
    public SimpleDateFormat getDateTimeMillisFormat() {
        return new SimpleDateFormat(PATTERN_DATE_TIME_MILLIS);
    }

    /**
     * yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public SimpleDateFormat getDateTimeFormat() {
        return new SimpleDateFormat(PATTERN_DATE_TIME);
    }

    /**
     * yyyy-MM-dd
     *
     * @return
     */
    public SimpleDateFormat getDateFormat() {
        return new SimpleDateFormat(PATTERN_DATE);
    }

    /**
     * 拷贝list
     *
     * @param source   源数据
     * @param function 映射函数
     * @param <S>      源类
     * @param <R>      目标类
     * @return
     */
    public <S, R> List<R> copyList(List<S> source, Function<S, R> function) {
        if (null == source || source.isEmpty()) {
            return new ArrayList<>(0);
        }
        List<R> target = new ArrayList<>();
        if (null != CLASS_PAGE_HELPER && CLASS_PAGE_HELPER.isAssignableFrom(source.getClass())) {
            // com.github.pagehelper.Page
            try {
                target = (List<R>) CLASS_PAGE_HELPER.getDeclaredConstructor().newInstance();
            } catch (InvocationTargetException | NoSuchMethodException | InstantiationException |
                     IllegalAccessException e) {
                target = new ArrayList<>();
            }
            BeanCopier.create(source, target, null).copy();
        }
        target.clear();
        List<R> copyData = source.stream().map(function).toList();
        target.addAll(copyData);
        return target;
    }

    /**
     * 拷贝list
     *
     * @param source   源数据
     * @param supplier 目标类实例化函数
     * @param <S>      源类
     * @param <R>      目标类
     * @return
     */
    public <S, R> List<R> copyList(List<S> source, Supplier<R> supplier) {
        return copyList(source, e -> {
            R target = supplier.get();
            if (e != null) {
                BeanCopier.create(e, target, null).copy();
            }
            return target;
        });
    }

}
